package com.young.coordin.server.service.impl;

import com.young.coordin.server.dao.ICoordinRegisterDao;
import com.young.coordin.server.model.CoordinResultEnum;
import com.young.coordin.server.model.RegisterDO;
import com.young.coordin.server.service.ICoordinRegisterService;
import com.young.coordin.server.util.CoordinResponseBuilder;
import com.young.interfaces.coordin.model.HeartbeatDTO;
import com.young.interfaces.coordin.model.RegisterDTO;
import com.young.interfaces.coordin.model.CoordinResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 注册服务
 * Created by Admin on 2020/12/10.
 */
@Service
public class CoordinRegisterServiceImpl implements ICoordinRegisterService {

    private static final Logger logger = LoggerFactory.getLogger(CoordinRegisterServiceImpl.class);

    /**
     * 注册dao
     */
    @Autowired
    ICoordinRegisterDao coordinRegisterDao;

    /**
     * 注册
     *
     * @param registerDTO
     */
    @Override
    public CoordinResponse register(RegisterDTO registerDTO) {
        //查询是否已有注册信息
        RegisterDO register = coordinRegisterDao.getClientRegisterInfo(registerDTO.getIp(), registerDTO.getPort());
        logger.info("[协调服务注册] 获取客户端注册信息,客户端ip={},端口号={},注册信息={}", registerDTO.getIp(), registerDTO.getPort(), register);

        //若没有注册信息则先插入一条注册数据
        if (register == null) {
            //对象转换
            register = RegisterDO.valueOf(registerDTO);
            //入库
            coordinRegisterDao.insert(register);
            logger.info("[协调服务注册] 插入注册信息={}", register);
            return CoordinResponseBuilder.buildSuccess(register.getHeartbeatVersion());
        } else {
            //若已存在则直接返回
            logger.info("[协调服务注册] 当前客户端已存在注册信息={}", register);
            return CoordinResponseBuilder.buildSuccess(register.getHeartbeatVersion());
        }
    }

    /**
     * 心跳处理
     *
     * @param heartbeatDTO 心跳参数
     */
    @Override
    public CoordinResponse heartbeat(HeartbeatDTO heartbeatDTO) {
        //查询是否已有注册信息
        RegisterDO register = coordinRegisterDao.getClientRegisterInfo(heartbeatDTO.getIp(), heartbeatDTO.getPort());
        logger.info("[心跳处理] 获取客户端注册信息,客户端ip={},端口号={},注册信息={}", heartbeatDTO.getIp(), heartbeatDTO.getPort(), register);

        //若没有注册信息则先插入一条注册数据
        if (register == null) {
            logger.error("[心跳处理] 查询注册信息失败,入参={}", heartbeatDTO);
            return CoordinResponseBuilder.buildFail(CoordinResultEnum.NONE_REGISTER);
        }

        //若入参版本号过低则阻断, 并返回最新版本号
        if (heartbeatDTO.getVersion() <= register.getHeartbeatVersion()) {
            logger.error("[心跳处理] 入参版本号低于服务端记录的版本号,入参={},服务端注册信息={}", heartbeatDTO, register);
            CoordinResponse response = CoordinResponseBuilder.buildFail(CoordinResultEnum.LOW_VERSION);
            response.setVersion(register.getHeartbeatVersion());
            return response;
        }

        //若已经注册, 则更新
        int num = coordinRegisterDao.updateHbVersion(register.getClientIp(), register.getClientPort(), heartbeatDTO.getVersion());
        if (num != 1) {
            logger.error("[心跳处理] 版本号更新失败,入参={},当前事务查询的注册信息={}", heartbeatDTO, register);
            return CoordinResponseBuilder.buildFail(CoordinResultEnum.HEARTBEAT_UPDATE_FAIL);
        }

        //更新成功则返回最新版本号
        return CoordinResponseBuilder.buildSuccess(heartbeatDTO.getVersion());
    }
}
